
#ifndef _TTG_PIPELINE_BASICNODE_
#define _TTG_PIPELINE_BASICNODE_
#include "Common/Definitions.h"

#include "Common/Structures.h"
#include "NodeInfo.h"
#include "NodeState.h"
#include "../PipelineContexts.h"

namespace ttg_internal
{
	namespace pipeline
	{
		//Interface, that defines common methods for all nodes and subsystems.
		class BasicNode :public ttg::structures::NamedObject
		{
			private:
				NodeInfo info;									//information about this node.
				ttg::pipeline::ContextMap<NodeState> states;	//current node state.
				InternalContext *context;						//context, that is common for all nodes.
			public:
				inline BasicNode(const char *name, bool is_serial)
					:NamedObject(name), info(name, is_serial, false)
				{ context = NULL; }
				//Notifies node about new iteration.
				//Should send "startIteration" to all connected output-nodes.
				//Note: it will be called by each input-node.
				virtual void startIteration(ttg::pipeline::ContextID ID) = 0;
				//Notifies node about end of iteration.
				//Should send "endIteration" to all connected output-nodes.
				//Note: it will be called by each input-node.
				virtual void finishIteration(ttg::pipeline::ContextID ID) = 0;
				//This method will be called after any pipeline modification.
				//In case of error should throws Error().
				virtual void onPipelineRecreation() = 0;
				//Returns ID of current context.
				//Should be called only inside of onBegin()/onEnd(), process(), etc.
				inline ttg::pipeline::ContextID getContextID()
				{ return getIContext().getDataBuffer().getContextID(); }
				//Returns current pipeline context with some information about launch.
				//Should be called only inside of onBegin()/onEnd(), process(), etc.
				inline ttg::pipeline::PipelineContext &getContext()
				{ return getIContext().getPipelineContext(); }
				//Returns information about node.
				inline NodeInfo &getInfo()
				{ return info; }
				//Returns current state of node (for required context).
				inline NodeState &getState(ttg::pipeline::ContextID ID)
				{ return states[ID]; }
				//Returns internal context.
				//Internal note: in case of internal error throws internal ttg::Error().
				InternalContext &getIContext();
				//Sets internal context for this node.
				inline void setContext(InternalContext *context)
				{ this->context = context; }
		};
	}
}

#endif
